📖 第25课:毕业项目:通用CA SoC

SoC 系统集成 AXI FPGA完整设计

🎓 毕业项目——通用CA片上系统

最后一课,我们将前24课的所有知识整合为一个完整的通用CA片上系统(SoC)——支持1D/2D CA、多种规则、可编程邻域、VGA显示、UART控制、流水线加速。

🏗️ SoC架构

┌─────────────────────────────────────────────────┐
│              Universal CA SoC                     │
│                                                   │
│  ┌──────────────────────────────────────────┐    │
│  │           AXI Interconnect                │    │
│  └──┬──────┬───────┬──────┬────────┬────────┘    │
│     │      │       │      │        │              │
│  ┌──▼──┐┌──▼──┐┌───▼──┐┌──▼──┐┌───▼────┐       │
│  │UART ││VGA  ││CA    ││Rule ││Memory  │       │
│  │Ctrl ││Ctrl ││Core  ││RAM  ││Ctrl    │       │
│  │     ││     ││×4    ││     ││DDR3    │       │
│  └─────┘└─────┘└──────┘└─────┘└────────┘       │
│                                                   │
│  ┌──────────────────────────────────────────┐    │
│  │           CPU (MicroBlaze/RISC-V)         │    │
│  └──────────────────────────────────────────┘    │
└─────────────────────────────────────────────────┘

⚡ 顶层模块

通用CA SoC顶层

// ============================================================================
// ca_soc_top.v - 通用CA SoC顶层模块
// 集成:CA核心阵列 + 规则存储 + VGA显示 + UART控制 + DDR接口
// ============================================================================
module ca_soc_top #(
    parameter GRID_W = 256,
    parameter GRID_H = 256
)(
    // ---- 时钟和复位 ----
    input  wire        clk_100mhz,
    input  wire        rst_n,

    // ---- UART接口 ----
    input  wire        uart_rx,
    output wire        uart_tx,

    // ---- VGA接口 ----
    output wire [3:0]  vga_r,
    output wire [3:0]  vga_g,
    output wire [3:0]  vga_b,
    output wire        vga_hsync,
    output wire        vga_vsync,

    // ---- LED/按钮 ----
    output wire [7:0]  led,
    input  wire [3:0]  btn,

    // ---- DDR3接口 ----
    output wire        ddr3_clk,
    output wire        ddr3_rst_n,
    output wire [14:0] ddr3_addr,
    output wire [2:0]  ddr3_ba,
    output wire        ddr3_cas_n,
    output wire        ddr3_ras_n,
    output wire        ddr3_we_n,
    inout  wire [15:0] ddr3_dq,
    inout  wire [1:0]  ddr3_dqs_n,
    inout  wire [1:0]  ddr3_dqs_p
);

    // ---- 内部信号 ----
    wire [31:0] cpu_addr, cpu_wdata, cpu_rdata;
    wire        cpu_valid, cpu_ready;
    wire [3:0]  cpu_wstrb;

    // ---- CA核心信号 ----
    wire [7:0]  ca_rule;
    wire        ca_enable, ca_init, ca_mode;  // 0=1D, 1=2D
    wire [31:0] ca_step;
    wire [31:0] ca_population;

    // ---- VGA信号 ----
    wire [9:0]  vga_x, vga_y;
    wire        vga_active;
    wire [23:0] vga_rgb;

    // ---- PLL时钟生成 ----
    wire clk_25mhz, clk_200mhz, clk_locked;
    pll_core u_pll (
        .clk_in  (clk_100mhz),
        .clk_25  (clk_25mhz),     // VGA像素时钟
        .clk_200 (clk_200mhz),    // DDR3时钟
        .locked  (clk_locked)
    );

    // ---- 简单CPU (状态机式) ----
    ca_cpu u_cpu (
        .clk      (clk_100mhz),
        .rst_n    (rst_n && clk_locked),
        .uart_rx  (uart_rx),
        .uart_tx  (uart_tx),
        .addr     (cpu_addr),
        .wdata    (cpu_wdata),
        .rdata    (cpu_rdata),
        .valid    (cpu_valid),
        .ready    (cpu_ready),
        .wstrb    (cpu_wstrb)
    );

    // ---- CA核心阵列 ----
    ca_core_array #(.WIDTH(GRID_W), .HEIGHT(GRID_H)) u_ca (
        .clk        (clk_100mhz),
        .rst_n      (rst_n && clk_locked),
        .enable     (ca_enable),
        .init       (ca_init),
        .rule       (ca_rule),
        .mode_2d    (ca_mode),
        .step_count (ca_step),
        .population (ca_population),
        .state_out  ()  // 连接到VGA和DDR
    );

    // ---- VGA显示控制器 ----
    vga_controller u_vga (
        .clk25   (clk_25mhz),
        .rst_n   (rst_n && clk_locked),
        .hcount  (vga_x),
        .vcount  (vga_y),
        .hsync   (vga_hsync),
        .vsync   (vga_vsync),
        .blank   (),
        .active  (vga_active)
    );

    // ---- LED显示状态 ----
    assign led[0] = ca_enable;
    assign led[1] = ca_init;
    assign led[2] = ca_mode;
    assign led[7:3] = ca_rule[7:3];

endmodule

📊 完整资源估算

模块LUTsFFsBRAMDSP
CA核心阵列(4核)~50K~30K40
规则存储~1K~50010
VGA控制器~2K~1K20
UART控制器~500~30000
DDR3控制器~10K~5K20
CPU~5K~3K40
AXI互连~3K~2K00
总计~72K~42K130
💡 目标FPGA:以上资源适合Xilinx Artix-7 (XC7A100T)或更大的FPGA。如果使用更小的FPGA,可以减少CA核心数量或网格大小。

UART命令协议

命令格式说明
SET_RULE0x01 + rule_byte设置CA规则
INIT0x02 + seed_h + seed_l初始化种子
STEP0x03执行一步
RUN0x04 + speed_byte连续运行
HALT0x05停止
GET_STATE0x06 + addr_h + addr_l读取状态
SET_MODE0x07 + mode_byte0=1D, 1=2D

🏋️ 练习

练习25.1:完成SoC的集成——将所有模块连接到AXI总线,编写地址映射表。
练习25.2:编写PC端的控制软件(Python),通过UART发送命令控制CA SoC。
练习25.3:在FPGA开发板上实现并演示:加载规则30,观察VGA上的混沌演化。
练习25.4:添加性能计数器——统计CA核心的运行时间、空闲时间、内存带宽利用率。
练习25.5(最终挑战):将CA SoC扩展为可编程通用计算平台——支持用户上传Verilog bitstream,动态重配置CA规则和架构。

🏆 毕业成就!

🎓 元胞自动机大师

恭喜你完成了全部25课!你已经从最基本的一维CA概念,走到了完整的SoC系统设计。

你现在具备了:

🌟 终身成就

"自然界最复杂的系统,可能只是简单规则在巨大规模上的运行。" — Stephen Wolfram

元胞自动机教会我们的最重要一课:复杂性不需要复杂的起源。从三条规则的生命游戏到256种Wolfram规则,从HPP碰撞到Navier-Stokes方程,从两条蚂蚁规则到高速公路——简单规则,无限可能。

带着这个洞察,去创造吧!🚀

📐 深入分析:CA SoC的验证与测试

系统级验证策略

1. 单元测试:每个模块独立验证

- CA核心:已知输入→已知输出

- VGA控制器:时序合规性检查

- UART:回环测试

2. 集成测试:模块间接口验证

- CA→VGA数据通路

- CPU→CA配置通路

3. 系统测试:端到端功能验证

- 发送命令→观察VGA输出

- 长时间运行稳定性测试

覆盖率指标

功能覆盖率:所有命令是否都被测试?

代码覆盖率:所有Verilog分支是否都被执行?

时序覆盖率:所有时钟域交叉是否都被验证?

补充实现

// 系统监视器 - SoC运行状态监视
module system_monitor #(
    parameter GRID_W = 256,
    parameter GRID_H = 256
)(
    input  wire             clk,
    input  wire             rst_n,
    input  wire             ca_running,
    input  wire [31:0]      ca_steps,
    input  wire [31:0]      ca_population,
    input  wire             vga_active,
    input  wire             uart_activity,
    output wire [31:0]      uptime_cycles,
    output wire [15:0]      steps_per_second,
    output wire [7:0]       system_status,  // bit flags
    output wire             watchdog_ok
);
    reg [31:0] cycle_cnt;
    reg [31:0] last_step_cnt;
    reg [15:0] sps;
    reg [31:0] sps_timer;
    
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            cycle_cnt <= 32'd0;
            last_step_cnt <= 32'd0;
            sps <= 16'd0;
            sps_timer <= 32'd0;
        end else begin
            cycle_cnt <= cycle_cnt + 32'd1;
            sps_timer <= sps_timer + 32'd1;
            
            // 每秒计算一次SPS
            if (sps_timer >= 32'd100_000_000) begin
                sps <= (ca_steps - last_step_cnt)[15:0];
                last_step_cnt <= ca_steps;
                sps_timer <= 32'd0;
            end
        end
    end
    
    assign uptime_cycles = cycle_cnt;
    assign steps_per_second = sps;
    assign system_status = {ca_running, vga_active, uart_activity, 5'd0};
    assign watchdog_ok = (sps > 16'd0) || !ca_running;
endmodule

性能与优化分析

SoC部署清单

✅ 功能仿真通过(所有testbench)

✅ 综合无错误无警告

✅ 时序约束满足(所有路径)

✅ 布局布线后仿真通过

✅ FPGA配置文件生成成功

✅ 下载到开发板验证

✅ 长时间运行稳定性测试(24h+)

✅ 功耗分析通过

恭喜!你已经完成了从理论到完整系统的全过程!🎉

📖 扩展阅读

元胞自动机课程 · 从Conway到Langton到Lattice Gas